﻿//----------------------------------------------------------------
//CodeArt (2011)
//
//Author: jianyi0115@163.com
//Created: 2011-6-20
//
//History:
// 
//----------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint;
using System.Xml;
using System.Reflection;
using System.Web.UI.WebControls.WebParts;
using WebPart = System.Web.UI.WebControls.WebParts.WebPart;

namespace CodeArt.SharePoint.SmartQuery
{
    public abstract class ListWebPartQueryManager
    {
        public abstract void ChangeQuerySchema(string query);
        public abstract void RestoreQuerySchema();

        
        public static void ChangeWebPartsQuery(SPList curList, WebPartCollection parts, string qxml)
        {
            if (String.IsNullOrEmpty(qxml)) return;

            string listId = "{" + curList.ID.ToString() + "}";

            foreach (WebPart wp in parts)
            {
                if (wp is Microsoft.SharePoint.WebPartPages.ListViewWebPart)
                {
                    Microsoft.SharePoint.WebPartPages.ListViewWebPart listWp = (Microsoft.SharePoint.WebPartPages.ListViewWebPart)wp;
                    if (String.Compare(listWp.ListName, listId, true) != 0) continue;
                    var queryManager = new ListViewWebPartQueryManager(listWp, curList.Views[new Guid(listWp.ViewGuid)]);
                    if (String.IsNullOrEmpty(qxml))
                    {
                        queryManager.RestoreQuerySchema();
                    }
                    else
                    {
                        queryManager.ChangeQuerySchema(qxml);
                    }
                    break;
                }
                else if (wp.GetType().Name == "XsltListViewWebPart")
                {
                    var queryManager = new XsltListViewWebPartQueryManager(wp, curList);
                    if (String.IsNullOrEmpty(qxml))
                    {
                        queryManager.RestoreQuerySchema();
                    }
                    else
                    {
                        queryManager.ChangeQuerySchema(qxml);
                    }
                    break;
                }
            }
        }

        protected void ChangeSchemaXmlQuery(XmlDocument doc, string query)
        {
            if (String.IsNullOrEmpty(query)) return;

            string innerQuery = GetInnerQuery(query);
            if (innerQuery == "") return;

            XmlNode queryNode = doc.DocumentElement.SelectSingleNode("Query");
            //queryNode.InnerXml = qxml;

            XmlNode whereNode = queryNode.SelectSingleNode("Where");

            if (whereNode != null)
                queryNode.RemoveChild(whereNode);

            XmlNode newWhereNode = doc.CreateElement("Where");
            newWhereNode.InnerXml = innerQuery;

            queryNode.AppendChild(newWhereNode);

            XmlNode viewEmptyNode = doc.DocumentElement.SelectSingleNode("ViewEmpty");
            if (viewEmptyNode != null)
            {
                viewEmptyNode.InnerXml = "<HTML><![CDATA[<font color='red'><b>" +
                ResourcesHelper.GetResourceString("NoFoundItems", "未找到符合查询条件的记录。") + "</b></font>]]></HTML>";
            }
        }
        string GetInnerQuery(string q)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(q);
            return doc.DocumentElement.InnerXml;
        }
    }

    class ListViewWebPartQueryManager : ListWebPartQueryManager
    {
        private ListViewWebPart webpart;
        private SPView view;
        public ListViewWebPartQueryManager(ListViewWebPart wp, SPView view)
        {
            this.webpart = wp;
            this.view = view;
        }
        public override void ChangeQuerySchema(string query)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(this.webpart.ListViewXml);
            ChangeSchemaXmlQuery(doc, query);
            this.webpart.ListViewXml = doc.InnerXml;
        }
        public override void RestoreQuerySchema()
        {
            webpart.ListViewXml = this.view.HtmlSchemaXml; //还
        }
    }
    /// <summary>
    /// for 2010 XsltListViewWebPart
    /// 为了兼容07，用反射调用。
    /// </summary>
    class XsltListViewWebPartQueryManager : ListWebPartQueryManager
    {
        private WebPart webpart;
        private SPView view;
        private SPList list;
        private PropertyInfo xmlDefinitionProperty;
        private PropertyInfo viewGuidProperty;
        public XsltListViewWebPartQueryManager(WebPart wp, SPList list)
        {            
            this.webpart = wp;            
            xmlDefinitionProperty = wp.GetType().GetProperty("XmlDefinition");
            viewGuidProperty = wp.GetType().GetProperty("ViewGuid");
            this.view = list.Views[new Guid(viewGuidProperty.GetValue(wp,null).ToString())];
        }
        public override void ChangeQuerySchema(string query)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xmlDefinitionProperty.GetValue(this.webpart, null).ToString());
            ChangeSchemaXmlQuery(doc, query);
            this.xmlDefinitionProperty.SetValue(this.webpart, doc.InnerXml, null);
        }
        public override void RestoreQuerySchema()
        {
            this.xmlDefinitionProperty.SetValue(this.webpart,  this.view.HtmlSchemaXml, null);
        }        
    }
}
